using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace SunshineFarmWord
{
    [RequireComponent(typeof(PlayerInput))]
    public class Player : MonoBehaviour
    {
        private class TakeDistanceObj
        {
            public bool isUpdate = false;
            public Vector2 Distance;
            public float Time;
        }


        [field: Header("参考数据")]
        [field: SerializeField, Tooltip("玩家需要的数据")]
        public PlayerSO Data { get; private set; }
        [field: SerializeField, Header("动画事件触发器的子物体列表")]
        public List<AnimationEventTrigger> childrenAnimationEventList;
        [field: SerializeField, Header("玩家模型节点")]
        public GameObject PlayerSkinNode;
        //
        [field: Header("动画状态名称")]
        [field: SerializeField]
        public CustomizeAnimationData AnimationData { get; private set; }
        public Rigidbody2D Rigidbody2D { get; private set; }
        public PlayerInput PlayerInput { get; private set; }
        private PlayerStateMachine stateMachine;

        private TakeDistanceObj _takeDistanceObj = new TakeDistanceObj();

        void Awake()
        {
            this.Rigidbody2D = GetComponent<Rigidbody2D>();
            this.PlayerInput = GetComponent<PlayerInput>();

            //初始化 动画事件
            InitAnimationEventTriggerData();

            // 初始化动画数据
            AnimationData.Initialize();

            //初始化状态
            stateMachine = new PlayerStateMachine(this);

            //初始化玩家朝向
            //SetPlayerFace(PlayerSO.PlayerFaceEnum.Right);
        }

        void Start()
        {
            stateMachine.ChangeState(stateMachine.IdlingState);
        }

        void Update()
        {
            stateMachine.HandleInput();

            stateMachine.Update();

        }

        void FixedUpdate()
        {
            stateMachine.PhysicsUpdate();

            TackDisUpdate();
        }

        void OnDestroy()
        {
            DestroyAnimationEventTriggerData();
        }

        #region Main function
        //移动一段距离
        private void TackDisUpdate()
        {
            if (!_takeDistanceObj.isUpdate) return;
            transform.position = Vector2.Lerp(transform.position, new Vector2(transform.position.x + _takeDistanceObj.Distance.x, transform.position.y + _takeDistanceObj.Distance.y), _takeDistanceObj.Time);
        }


        private void InitAnimationEventTriggerData()
        {
            if (childrenAnimationEventList.Count == 0) return;

            childrenAnimationEventList[0].onAnimationEnterEvent += OnMovementStateAnimationEnterEvent;
            childrenAnimationEventList[0].onAnimationExitEvent += OnMovementStateAnimationExitEvent;
            childrenAnimationEventList[0].onAnimationTransitionEvent += OnMovementStateAnimationTransitionEvent;
        }

        private void DestroyAnimationEventTriggerData()
        {
            if (childrenAnimationEventList.Count == 0) return;
            childrenAnimationEventList[0].onAnimationEnterEvent -= OnMovementStateAnimationEnterEvent;
            childrenAnimationEventList[0].onAnimationExitEvent -= OnMovementStateAnimationExitEvent;
            childrenAnimationEventList[0].onAnimationTransitionEvent -= OnMovementStateAnimationTransitionEvent;
        }
        #endregion

        #region public function
        public PlayerStateReusableData GetPlayerReusableData()
        {
            return stateMachine.ReusableData;
        }
        public PlayerSO GetPlayerData(){
            return Data;
        }
        // 播放动画
        public void StartAnimation(int animationHash)
        {
            //
            if (childrenAnimationEventList.Count == 0) return;
            foreach (AnimationEventTrigger item in childrenAnimationEventList)
            {
                item.StartAnimation(animationHash);
            }
        }
        // 停止动画
        public void StopAnimation(int animationHash)
        {
            if (childrenAnimationEventList.Count == 0) return;
            foreach (AnimationEventTrigger item in childrenAnimationEventList)
            {
                item.StopAnimation(animationHash);
            }
        }
        // 设置玩家朝向
        public void SetPlayerFace(PlayerSO.PlayerFaceEnum playerFace)
        {
            stateMachine.ReusableData.playerFaceEnum = playerFace;
            // 0->左;1->右
            PlayerSkinNode.transform.Rotate(new Vector3(0, playerFace == PlayerSO.PlayerFaceEnum.Right ? -180 : 180, 0));
        }
        //获取玩家朝向
        public PlayerSO.PlayerFaceEnum GetPlayerFace()
        {
            return stateMachine.ReusableData.playerFaceEnum;
        }

        //移动一段距离
        public void TakeDistance(Vector2 normal, float time)
        {
            _takeDistanceObj.Distance = normal;
            _takeDistanceObj.Time = time;
            _takeDistanceObj.isUpdate = true;
            //Rigidbody2D.MovePosition(Rigidbody2D.position + normal);
            //transform.position += (Vector3)normal;
            //transform.position = Vector2.Lerp(transform.position, new Vector2(transform.position.x + normal.x,transform.position.y + normal.y), 99f);

        }

        public void TakeDistanceOver()
        {
            _takeDistanceObj.isUpdate = false;
        }
        #endregion


        #region 动画事件处理
        public void OnMovementStateAnimationEnterEvent()
        {
            stateMachine.OnAnimationEnterEvent();
        }

        public void OnMovementStateAnimationExitEvent()
        {
            stateMachine.OnAnimationExitEvent();
        }

        public void OnMovementStateAnimationTransitionEvent()
        {
            stateMachine.OnAnimationTransitionEvent();
        }
        #endregion


        #region 碰撞处理
        private void OnTriggerEnter2D(Collider2D collider)
        {
            //
            stateMachine.OnTriggerEnter2D(collider);
        }

        private void OnTriggerExit2D(Collider2D collider)
        {
            stateMachine.OnTriggerExit2D(collider);
        }

        //碰撞中
        private void OnTriggerStay2D(Collider2D collider)
        {
            stateMachine.OnTriggerStay2D(collider);
        }
        #endregion

        #region 物理碰撞处理
        private void OnCollisionEnter2D(Collision2D collision)
        {
            stateMachine.OnCollisionEnter2D(collision);
        }

        private void OnCollisionExit2D(Collision2D collision)
        {
            stateMachine.OnCollisionExit2D(collision);
        }
        #endregion
    }
}
